﻿using UnityEngine;
using System.Collections;
using Memo.Electricity.Engine;
using UnityEngine.SceneManagement;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Memo.Electricity.Game
{
	public class CRelay : MemoBehaviour
	{
		#region 电流计算

		/// <summary>
		/// 从玩家1到玩家2的电流的连结路径
		/// </summary>
		public static List<Transform> ConnectPath { get; private set; } = null;

		/// <summary>
		/// 两个玩家是否已经连接上了
		/// </summary>
		public static bool IsConnected { get; private set; } = false;

		private static CTick sCaculateTick = null;

		public static void Init()
		{
			//启动路径计算的Tick
			IsConnected = false;
			ConnectPath = null;
			if (sCaculateTick != null)
			{
				Destroy();
			}
			sCaculateTick = CTickMgr.Inst.RegisterTick(CaculateConnectPath, 0.1f);

			//注册取消事件
			//Action<Scene, Scene> callback = null;
			//callback = (Scene s1, Scene s2) =>
			// {
			//	 Destroy();
			//	 CEventMgr.Inst.RemoveListener(EEventType.OnActiveSceneChanged, callback);
			// };
			//CEventMgr.Inst.AddListener(EEventType.OnActiveSceneChanged, callback);
		}

		public static void Destroy()
		{
			//停止路径计算Tick并清理数据
			CTickMgr.Inst.DeregisterTick(sCaculateTick);
			sCaculateTick = null;
		}

		private static void CaculateConnectPath()
		{
			Stack<Transform> nodeStack = new Stack<Transform>();
			HashSet<Transform> nodeSet = new HashSet<Transform>();

			float connectRange = PlayerManager.Inst.ElectricityLength; //电流的长度
			Func<Transform, bool> dfs = null; //实际的搜索算法，写成Lambda然后做递归
			dfs = (Transform trans) =>
			{
				nodeStack.Push(trans);
				nodeSet.Add(trans);

				Collider2D[] nodes = Physics2D.OverlapCircleAll(trans.position, connectRange);
				//先判断能不能直接连接
				foreach (var collider in nodes)
				{
					Transform next = collider.transform;
					if (!nodeSet.Contains(next))
					{
						if (next.CompareTag("Player"))
						{
							//由于玩家一已经在nodeSet中，所以这里一定是玩家二
							nodeStack.Push(next);
							return true;
						}
					}
				}
				//若不能，再搜
				foreach (var collider in nodes)
				{
					Transform next = collider.transform;
					if (!nodeSet.Contains(next))
					{
						if (next.CompareTag("Player"))
						{
							//由于玩家一已经在nodeSet中，所以这里一定是玩家二
							nodeStack.Push(next);
							return true;
						}
						else
						{
							CRelay relay = next.GetComponent<CRelay>();
							if (relay && Vector3.Distance(relay.ConnectPos, trans.position) < connectRange)
							{
								bool flag = dfs(relay.transform);
								if (flag == true)
									return true;
							}
						}
					}
				}

				nodeSet.Remove(trans);
				nodeStack.Pop();
				return false;//搜索失败，玩家没有连结上
			};
			if (dfs(PlayerManager.Inst.Player1.transform))
			{
				IsConnected = true;
				ConnectPath = nodeStack.ToList();
				ConnectPath.Reverse();
			}
			else
			{
				IsConnected = false;
				ConnectPath = null;
			}

		}

		#endregion

		#region 拾取逻辑

		[SerializeField] private bool bPickable;
		public bool Pickable { get => bPickable; }

		#endregion

		public Vector3 ConnectPos { get => mConnectLoaclPos + transform.position; }
		[Header("电流的连接点"), SerializeField] 
		private Vector3 mConnectLoaclPos;
		[HideInInspector]
		public bool isPicked = false;

	}
}